﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#include "IActionManager.h"
#include "IBuiltInParameterDefinitionManager.h"
#include "ExprHelper.h"

#include "IFamilyDimensionConstraint.h"
#include "IFamilyManager.h"

#include "IFamily.h"
#include "GbmpBuiltInParameterDefinitions.h"
#include "GcmpBuiltInCategoryUniIdentities.h"
#include "GmStyleSheetHelper.h"
#include "IElementParameterBindings.h"
#include "IParameterBinding.h"
#include "IPublishConfig.h"
#include "ParaDefineDlg.h"
#include "ParameterType.h"
#include "SharedParaDefineDlg.h"
#include "UiCommonDialog.h"
#include "UnitUniIdentities.h"
#include "FamilyElementUtils.h"
#include <QtCore/QVariant>
#include <QtCore/qnamespace.h>
#include "ui_paradefinedlg.h"
#include "FormulaUtil.h"
#include <regex>
#include "IBehaviorConfig.h"
#include "GbmpConstants.h"
#include "UiDocumentViewUtils.h"
#include "QtWidgets/qcompleter.h"
#include "QtWidgets/qstyleditemdelegate.h"
#include "ExprAssistantDlg.h"
#include <QEvent>
#include <QKeyEvent>
#include "JournalUtils.h"
#include "IGraphicsMaterial.h"
#include "IElementParameters.h"
#include "IElementBasicInformation.h"
#include "IParameter.h"
#include "IFamilyType.h"
#include "IParameterValueStorage.h"
#include "IFamilyParameterDefinition.h"
#include "IParameterDefinitionLibrary.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

#pragma execution_character_set("utf-8")

using namespace gcmp;

namespace gfam
{
    DelimitedCompleter::DelimitedCompleter(QLineEdit *parent, const QStringList &list)
        : QCompleter(list, parent)
    {
        m_isNeedEscape = false;
        m_position = -1;
        m_isNeedUpdate = false;
        parent->setCompleter(this);
    }

    QString DelimitedCompleter::pathFromIndex(const QModelIndex &index) const 
    {
        QLineEdit *lineEdit = qobject_cast<QLineEdit*>(parent());
        DBG_WARN_AND_RETURN_UNLESS(lineEdit, QString(), L"lineEdit为空", L"paramodel", L"2024-02-20");
        QString qText = lineEdit->text();
        QString qAutoString = index.data(Qt::EditRole).toString();
        // originalString为“参数：”或“函数：”开头，其长度至少为3
        if (qAutoString.size() < 3)
        {
            return qText;
        }

        QString originalString = qAutoString;
        // 删除字符串首部的“参数：”或“函数：”开头
        qAutoString = qAutoString.right(qAutoString.size() - 3);
        int position = lineEdit->cursorPosition();
        if (!m_isNeedUpdate)
        {
            m_position = position;
            return qText;
        }

        m_isNeedUpdate = false;
        // 处理嵌套括号的情况
        if (position < qText.size())
        {
            QString string1 = qText.left(position);
            QString string2 = qText.right(qText.size() - position);
            
            // 光标前有效字符串长度及其内容
            int iValidStringNum1 = 0;
            for (auto iter = string1.rbegin(); iter != string1.rend(); ++iter)
            {
                if (*iter == '+' || *iter == '-' || *iter == '*' || *iter == '/' || *iter == '(' || *iter == '=')
                {
                    break;
                }
                iValidStringNum1++;
            }
            QString qValidString1 = string1.left(string1.size() - iValidStringNum1);

            // 光标后有效字符串长度及其内容
            int iValidStrNum2 = 0;
            for (auto iter = string2.begin(); iter != string2.end(); ++iter)
            {
                if (*iter == '+' || *iter == '-' || *iter == '*' || *iter == '/' || *iter == ')')
                {
                    break;
                }
                iValidStrNum2++;
            }
            QString qValidString2 = string2.right(string2.size() - iValidStrNum2);
            if (originalString.startsWith("函数"))
            {
                m_position = qValidString1.size() + qAutoString.size() - 1;
            }
            else
            {
                m_position = qValidString1.size() + qAutoString.size();
            }

            qText = qValidString1 + qAutoString + qValidString2;
            return qText;
        }

        int inValidStrCount = 0;
        for (auto iter = qText.rbegin(); iter != qText.rend(); ++iter)
        {
            if (*iter == '-'|| *iter == '+'||*iter == '*' || *iter == '/' || *iter == '=' || *iter == '(')
            {
                break;
            }
            ++inValidStrCount;
        }

        qText = qText.left(qText.size() - inValidStrCount);
        qText = qText + qAutoString;
        if (originalString.startsWith("函数"))
        {
            m_position = qText.size() - 1;
        }
        return qText;
    }

    int DelimitedCompleter::GetPosition()
    {
        return m_position;
    }

    QStringList DelimitedCompleter::splitPath(const QString &path) const 
    {
        QStringList qStringList;
        QLineEdit *lineEdit = qobject_cast<QLineEdit*>(parent());
        DBG_WARN_AND_RETURN_UNLESS(lineEdit, qStringList, L"lineEdit为空", L"paramodel", L"2024-02-20");

        // 检查是否为嵌套参数
        int position = lineEdit->cursorPosition();
        QString qText = lineEdit->text();
        std::vector<QString> strVecs = { "asin()" ,"acos()" ,"atan()","if()" ,"sqrt()","pow()","Round()","Roundup()","Roundup()" };
        
        // 处理嵌套括号的情况
        if (position < qText.length())
        {
            QString string1 = qText.left(position);
            QString string2 = qText.right(qText.size() - position);

            // 如果光标后是表达式，不进行联想
            if (string2.startsWith("if()") || string2.startsWith("atan()") || string2.startsWith("asin()") || string2.startsWith("acos()") || string2.startsWith("sqrt()") || string2.startsWith("tan()") || string2.startsWith("sin()") || string2.startsWith("cos()") || string2.startsWith("pow()") || string2.startsWith("Round()") || string2.startsWith("Roundup()") || string2.startsWith("Rounddown()"))
            {
                qStringList << qText;
                return qStringList;
            }

            // 如果光标位置在表达式中间，如 ta|n() 此时不进行联想
            if (position > 0)
            {
                if (string1[position - 1] >= 'a' && string1[position] <= 'z' && ((string2[0] <= 'z'&&string2[0] >= 'a') || string2[0] == '('))
                {
                    qStringList << qText;
                    return qStringList;
                }

            }

            // 光标前有效字符串长度及其内容
            int iValidStrNum1 = 0;
            for (auto iter = string1.rbegin(); iter != string1.rend(); ++iter)
            {
                 if (*iter == '+' || *iter == '-' || *iter == '*' || *iter == '/' || *iter == '(' || *iter == '=')
                 {
                     break;
                 }
                 iValidStrNum1++;
            }
            QString qValidString1 = string1.mid(string1.size() - iValidStrNum1, string1.size());

            // 光标后有效字符串长度及其内容
            int iValidStrNum2 = 0;
            for (auto iter = string2.begin(); iter != string2.end(); ++iter)
            {
                if (*iter == '+' || *iter == '-' || *iter == '*' || *iter == '/' || *iter == ')')
                {
                    break;
                }
                iValidStrNum2++;
            }
            QString qValidString2 = string2.left(iValidStrNum2);
            QString str = qValidString1 + qValidString2;
            FOR_EACH(item, strVecs)
            {
                if (item.contains(str) && item != str)
                {
                    m_isNeedEscape = true;
                    break;
                }
            }

            qStringList << qValidString1 + qValidString2;
            return qStringList;
        }

        // 如果光标在末尾，获取尾部字符串
        QStringList inputData;
        inputData.clear();
        for (auto iter = path.rbegin(); iter != path.rend(); ++iter)
        {
            if (*iter == '+')
            {
                inputData = path.split("+");
            }
            else if(*iter == '-')
            {
                inputData = path.split("-");
            }
            else if (*iter == '*')
            {
                inputData = path.split("*");
            }
            else if (*iter == '/')
            {
                inputData = path.split("/");
            }
            else if (*iter == '=')
            {
                inputData = path.split("=");
            }
            else if (*iter == '(')
            {
                inputData = path.split("(");
            }

            if (!inputData.empty())
            {
                break;
            }
        }

        QString qStringPath;
        if (!inputData.empty())
        {
            QString qRealPath = inputData[inputData.size() - 1];
            if (!qRealPath.isEmpty())
            {
                if (qRealPath[qRealPath.size() - 1] == ')')
                {
                    qStringPath = path;
                    qStringList << path;
                }
                else
                {
                    qStringPath = qRealPath;
                    qStringList << qRealPath;
                }
            }
        }
        else
        {
            qStringPath = path;
            qStringList << path;
        }

        FOR_EACH(item, strVecs)
        {
            if (item.contains(qStringPath) && item != qStringPath)
            {
                m_isNeedEscape = true;
                break;
            }
        }

        return qStringList;
    }

    bool DelimitedCompleter::eventFilter(QObject * object, QEvent * event)
    {
        QLineEdit *lineEdit = qobject_cast<QLineEdit*>(parent());

        QEvent::Type type = event->type();
        if (type == QEvent::KeyPress)
        {
            m_isNeedUpdate = true;
            m_position = -1;
            QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);

            if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)
            {
                m_isNeedUpdate = false;
            }

            QAbstractItemView * pPopup = popup();
            if (pPopup)
            {
                QModelIndex index = pPopup->currentIndex();
                QAbstractItemModel * pModel = pPopup->model();
                if (pModel)
                {
                    if ((keyEvent->key() == Qt::Key_Up && index.row() == 0) || (keyEvent->key() == Qt::Key_Down && index.row() == pModel->rowCount() - 1))
                    {
                        return true;
                    }
                }
            }

            if (keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right)
            {
                if (m_isNeedEscape)
                {
                    Qt::KeyboardModifiers modifier = keyEvent->modifiers();
                    int keyValue = 0x01000000;
                    Qt::Key keyType = (Qt::Key)keyValue;
                    gcmp::OwnerPtr<QKeyEvent> keyEvent = NEW_AS_OWNER_PTR(QKeyEvent, QEvent::KeyPress, keyType, modifier);

                    QApplication::sendEvent(object, keyEvent.get());
                    m_isNeedEscape = false;
                }

            }
            else if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Escape || keyEvent->key() == Qt::Key_Return)
            {
                m_isNeedEscape = false;
            }
        }
        else if (type == QEvent::MouseButtonPress)
        {
            m_position = -1;
            m_isNeedEscape = false;
        }
        else if(type == QEvent::Hide)
        {
            m_isNeedEscape = false;
            m_isNeedUpdate = true;
        }
        else if (type == QEvent::FocusOut || type == QEvent::FocusIn || type == QEvent::Show||type == QEvent::Resize)
        {
            m_isNeedUpdate = true;
        }

        return QCompleter::eventFilter(object, event);
    }

    ParaDefineDlg::ParaDefineDlg(gfam::FamilyParameterType familyParameterType, bool bTypeEditable, QWidget *parent)
        : QDialog(parent, Qt::FramelessWindowHint)
    {
        ui = NEW_AS_OWNER_PTR(Ui::ParaDefineDlg);
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui != nullptr, L"ui为空", L"paramodel", L"2024-02-20");
        
        ui->setupUi(this);
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui->helpBtn != nullptr, L"ui->helpBtn为空", L"paramodel", L"2024-02-20");

        ui->helpBtn->setAutoDefault(false);
        ui->helpBtn->setShortcut(QKeySequence());
        ui->helpBtn->setIcon(QPixmap(":/image/PromptInformation/16x16.png"));
        ui->helpBtn->setToolTip(QString::fromStdWString(L"帮助"));

        DBG_WARN_AND_RETURN_VOID_UNLESS(GmStyleSheetHelper::Instance() != nullptr, L"GmStyleSheetHelper::Instance()为空", L"paramodel", L"2024-02-20");
        std::wstring styleSheetStr = GmStyleSheetHelper::Instance()->GetCurrentStyleData();
        setStyleSheet(QString::fromStdWString(styleSheetStr));

        this->resize(314, 377);
        ui->verticalLayout->setContentsMargins(0, 0, 0, 0);
        ui->verticalLayout2->setContentsMargins(0, 0, 0, 0);
        ui->verticalLayout_2->setContentsMargins(0, 0, 0, 10);
        ui->verticalLayout_3->setContentsMargins(0, 0, 0, 0);
        ui->groupBox->setStyleSheet("QGroupBox { margin-left: 10px; margin-right: 10px }");
        ui->groupBoxType->setStyleSheet("QGroupBox { margin-left: 10px; margin-right: 10px}");
        ui->groupBox->setContentsMargins(20, 10, 20, 10);
        ui->groupBoxType->setContentsMargins(20, 20, 20, 10);
        ///
        ui->gbmp_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
        ui->gbmp_title->setIconVisible(false);
        ui->gbmp_title->setMaxButtonVisible(false);
        ui->gbmp_title->setMinButtonVisible(false);
        ui->gbmp_title->setText(QString::fromStdWString(GBMP_TR(L"信息框")));
        this->setProperty("use_gbmp_title", true);
        connect(ui->gbmp_title, &GmTitleBar::closeRequested, this, &ParaDefineDlg::reject);
        connect(ui->gbmp_title, &GmTitleBar::moveRequested, this, &ParaDefineDlg::onMoveRequested);

        const IConfigRecord* pInHouseModeConfigRecord = IPublishConfig::GetConfigRecord(PublishConfigRecordNames::InHouseMode);
        if (pInHouseModeConfigRecord && !pInHouseModeConfigRecord->IsInternalIdentifyCodeValue())
        {
            ui->groupBoxType->setVisible(false);
            this->resize(314, 257);
        }

        if (familyParameterType == FamilyParameterType::Material)
        {
            // 计算出材质下拉列表中可见的内容
            std::vector<std::wstring> itemNames = CalcItemNamesInMaterialComboBox();
            QStringList qItemNames;
            FOR_EACH(itemName, itemNames)
            {
                qItemNames.push_back(QString::fromStdWString(itemName));
            }
            ui->materialComboBox->addItems(qItemNames);
        }
        ui->materialComboBox->setVisible(false);
        connect(ui->materialComboBox, &QComboBox::currentTextChanged, this, &ParaDefineDlg::OnMaterialComboBoxTextChanged);

        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"长度")), QVariant((int)FamilyParameterType::Length));
        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"角度")), QVariant((int)FamilyParameterType::Angle));
        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"数值")), QVariant((int)FamilyParameterType::Double));
        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"整数")), QVariant((int)FamilyParameterType::Integer));
        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"是/否")), QVariant((int)FamilyParameterType::Bool));
        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"文字")), QVariant((int)FamilyParameterType::String));
        ui->typeComboBox->addItem(QString::fromStdWString(GBMP_TR(L"材质")), QVariant((int)FamilyParameterType::Material));
        ui->typeComboBox->setEnabled(bTypeEditable);
        connect(ui->typeComboBox, &QComboBox::currentTextChanged, this, &ParaDefineDlg::OnTypeComboBoxTextChanged);
        ui->nameEdit->setFocus();
        std::wstring holderText = L"\"=\"";
        holderText += L"切换为表达式输入";
        ui->fomulalineedit->setPlaceholderText(QString::fromStdWString(holderText));

        if (JournalUtils::IsInReplay())
        {
            connect(ui->fomulalineedit, &QLineEdit::textChanged, this, &ParaDefineDlg::OnFormulaTextChangedInReplay);
        }

        InitCompleter();

        Int32 index = 0;//默认设为长度类型
        switch (familyParameterType)
        {
        case gfam::FamilyParameterType::Angle:
            index = 1;
            break;
        case gfam::FamilyParameterType::Double:
            index = 2;
            break;
        case gfam::FamilyParameterType::Integer:
            index = 3;
            break;
        case gfam::FamilyParameterType::Bool:
            index = 4;
            break;
        case gfam::FamilyParameterType::String:
            index = 5;
            break;
        case gfam::FamilyParameterType::Material:
            index = 6;
            break;
        case gfam::FamilyParameterType::Length:
        case gfam::FamilyParameterType::Invalid:
        case gfam::FamilyParameterType::Internal:
        case gfam::FamilyParameterType::NumOfTypes:
        case gfam::FamilyParameterType::Profile:
        default:
            break;
        }
        ui->typeComboBox->setCurrentIndex(index);
        m_pModifedParaDefinition = NULL;
        m_pFamilyManager = NULL;
        m_bModify = false;
        m_materialId = ElementId::InvalidID;
        connect(ui->buttonGroup, static_cast<void(QButtonGroup::*)(int, bool)>(&QButtonGroup::buttonToggled), this, &ParaDefineDlg::OnChangeButtonState);
        connect(ui->selectFileButton, &QPushButton::clicked, this, &ParaDefineDlg::OnSelectParameterFile);
        connect(ui->helpBtn, &QPushButton::clicked, this, &ParaDefineDlg::OnHelpButtonClicked);

        connect(ui->fomulalineedit, &QLineEdit::cursorPositionChanged, this, &ParaDefineDlg::OnCursorPositionChanged);

        setFixedHeight(height());
    }

    ParaDefineDlg::~ParaDefineDlg()
    {

    }

    QString GetStrNoSpace(const QString& str)
    {
        QStringList sl = str.split(" ", QString::SkipEmptyParts);
        QString strRet = "";
        for (int i = 0; i < sl.size(); i++)
        {
            strRet = strRet + sl.at(i);
        }

        return strRet;
    }

    void ParaDefineDlg::accept()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyManager != nullptr, L"m_pFamilyManager为空", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui != nullptr, L"ui为空", L"paramodel", L"2024-02-20");
       
        //得到对话框交互信息
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui->nameEdit != nullptr, L"ui->nameEdit为空", L"paramodel", L"2024-02-20");
        QString qstrName = ui->nameEdit->displayText();
        qstrName = GetStrNoSpace(qstrName);

        //名称
        std::wstring strName = qstrName.toStdWString();

        if (!ExprHelper::ValidateParamName(strName))
        {
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), GBMP_TR(L"参数名称不合理!"), (int)UiCommonDialog::ButtonType::OK);
            return;
        }

        m_strParaName = qstrName;

        //参数类型
        int nIdx = ui->typeComboBox->currentIndex();
        QVariant varData = ui->typeComboBox->itemData(nIdx);
        int nType = varData.toInt();
        //是否实例
        bool bInstance = ui->checkBox->checkState() == Qt::Checked;
        //表达式
        std::wstring strFormula = ui->fomulalineedit->displayText().toStdWString();
        bool bFomula = !strFormula.empty();

        // 参数值
        std::wstring strValue = L"";
        if (gcmp::StringUtil::StartWith(strFormula, L"="))
        {
            strFormula = strFormula.erase(0, 1);
        }
        else
        {
            strValue = strFormula;
            strFormula = L"";
            bFomula = false;
        }
        if (strValue != L"")
        {
            if (!CheckParameterValue(nType, strValue))
            {
                UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), GBMP_TR(L"参数值不合法！\n注意：区分值和表达式。\n表达式请先输入“ = ”，例如： = （A + B) * 2"), (int)UiCommonDialog::ButtonType::OK);
                return;
            }
        }
        m_strParaValue = strValue;

        // 处理表达式首部无效的0及小数点后末尾无效的0
        FamilyParameterType parameterType = (FamilyParameterType)nType;
        if ((parameterType == FamilyParameterType::Length || parameterType == FamilyParameterType::Angle
            || parameterType == FamilyParameterType::Double || parameterType == FamilyParameterType::Integer)
            && strFormula.length() > 2)
        {
            strFormula = FormulaUtil::DealWithInvalidZeroInFormula(strFormula);
        }
        //参数定义
        if (m_bModify)//编辑参数
        {
            if (!ModifyParameter(strName, nType, bInstance, bFomula, strFormula, strValue))
                return;
        }
        else
        {
            if (!CreateNewParameter(strName, nType, bInstance, bFomula, strFormula, strValue))
                return;
        }
        UpdateParamExprValues();

        QDialog::accept();
    }

    void ParaDefineDlg::InitToModify(const QString& qstrName)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyManager != nullptr, L"m_pFamilyManager为空", L"paramodel", L"2024-02-20");
        if (m_pFamilyManager)
        {
            //名称
            std::wstring strName = (const wchar_t *)qstrName.utf16();

            //判断是否存在
            m_pModifedParaDefinition = m_pFamilyManager->GetFamilyParameterDefinition(strName);
            if (m_pModifedParaDefinition != nullptr)
            {
                DBG_WARN_AND_RETURN_VOID_UNLESS(IBuiltInParameterDefinitionManager::Get() != nullptr, L"ui->nameEdit为空", L"paramodel", L"2024-02-20");
                const std::vector<const gcmp::IParameterDefinition*>& builtInParameterDefinitions = IBuiltInParameterDefinitionManager::Get()->GetBuiltInParameterDefinitions();
                FOR_EACH(pParamData, builtInParameterDefinitions)
                {
                    DBG_WARN_AND_CONTINUE_UNLESS(m_pModifedParaDefinition->GetBasicInformation() != nullptr, L"m_pModifedParaDefinition->GetBasicInformation()为空", L"paramodel", L"2024-02-20");
                    if (pParamData != nullptr && pParamData->GetUid() == m_pModifedParaDefinition->GetBasicInformation()->GetElementUid())
                    {
                        DBG_WARN_AND_CONTINUE_UNLESS(ui->nameEdit != nullptr, L"ui->nameEdit为空", L"paramodel", L"2024-02-20");
                        DBG_WARN_AND_CONTINUE_UNLESS(ui->checkBox != nullptr, L"ui->checkBox为空", L"paramodel", L"2024-02-20");
                        ui->nameEdit->setEnabled(false);
                        ui->checkBox->setEnabled(false);
                        break;
                    }
                }
                m_bModify = true;

                if (m_pModifedParaDefinition && m_pModifedParaDefinition->IsShared())
                {
                    ui->radioSharedParameterButton->setChecked(true);
                }

                //类型
                int nIdx = ui->typeComboBox->findData(QVariant((int)m_pModifedParaDefinition->GetParameterType()));

                ui->typeComboBox->setCurrentIndex(nIdx);
                ui->typeComboBox->setEnabled(false);

                //名称
                ui->nameEdit->setText(qstrName);

                //是否实例
                if (m_pModifedParaDefinition->IsInstance())
                {
                    ui->checkBox->setCheckState(Qt::Checked);
                }
                else
                {
                    ui->checkBox->setCheckState(Qt::Unchecked);
                }

                std::wstring formula = m_pModifedParaDefinition->GetFormula();
                if (!formula.empty())
                {
                    formula = L"=" + formula;
                    //表达式值
                    ui->fomulalineedit->setText(QString::fromStdWString(formula));
                }
                else
                {
                    QString qStrVaule = ParamValueToString(m_pModifedParaDefinition);
                    ui->fomulalineedit->setText(qStrVaule);
                }
            }
        }
    }

    void ParaDefineDlg::SetFormulaLineEditText(const QString & qStrValue)
    {
        if (ui && ui->fomulalineedit)
        {
            ui->fomulalineedit->setText(qStrValue);
        }
    }

    //打点
    std::wstring ParaDefineDlg::ConvertParameterType(FamilyParameterType type)
    {
        std::wstring wsParameterType = L"Invalid";
        switch (type)
        {
        case FamilyParameterType::Length:
            wsParameterType = L"length";
            break;
        case FamilyParameterType::Angle:
            wsParameterType = L"angle";
            break;
        case FamilyParameterType::Double:
            wsParameterType = L"data";
            break;
        case FamilyParameterType::Integer:
            wsParameterType = L"integer";
            break;
        case FamilyParameterType::Bool:
            wsParameterType = L"boole";
            break;
        case FamilyParameterType::String:
            wsParameterType = L"text";
            break;
        case FamilyParameterType::Material:
            wsParameterType = L"material";
            break;
        case FamilyParameterType::TextStyle:
            wsParameterType = L"text_style";
            break;
        default:
            DBG_WARN(L"暂不支持的类型", L"paramodel", L"2024-02-20");
            break;
        }
        return wsParameterType;
    }

    void gfam::ParaDefineDlg::UpdateComboBoxIndex(const IFamilyParameterDefinition* pParam, const QString& qStrValue)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(pParam != nullptr, L"pParam为空", L"paramodel", L"2024-02-20");
        if (m_pFamilyManager)
        {
            if (pParam->GetParameterType() == FamilyParameterType::Material)
            {
                if (ui && ui->materialComboBox)
                {
                    ui->materialComboBox->setCurrentText(qStrValue);
                }
            }
            else if (pParam->GetParameterType() == FamilyParameterType::TextStyle)
            {
                if (ui && ui->textStyeComboBox)
                {
                    ui->textStyeComboBox->setCurrentText(qStrValue);
                }
            }
        }
    }

    void ParaDefineDlg::OnSelectParameterFile()
    {
        SharedParaDefineDlg defDialog;
        //defDialog.SetFamilyManager(m_pFamilyManager);
        if (defDialog.exec() == Accepted)
        {
            if (m_sharedParaData = defDialog.GetSelectParamData())
            {
                //参数名称
                if (ui && ui->nameEdit)
                {
                    ui->nameEdit->setText(QString::fromStdWString(m_sharedParaData->Name));
                }

                //类型
                if (ui && ui->typeComboBox)
                {
                    int nIdx = ui->typeComboBox->findData(QVariant((int)m_sharedParaData->ParamType));
                    ui->typeComboBox->setCurrentIndex(nIdx);
                }

                //是否实例参数
                if (ui && ui->checkBox)
                {
                    ui->checkBox->setChecked(m_sharedParaData->IsInstance);
                }

                //公式
                if (ui && ui->fomulalineedit)
                {
                    ui->fomulalineedit->setText(QString::fromStdWString(m_sharedParaData->Formula));
                }

            }
        }
    }

    void ParaDefineDlg::OnChangeButtonState(int id, bool checked)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui != nullptr, L"ui为空", L"paramodel", L"2024-02-20");
        
        if (ui->radioSharedParameterButton->isChecked())
        {
            ui->nameEdit->setDisabled(true);
            ui->typeComboBox->setDisabled(true);

            if (m_bModify)
                ui->selectFileButton->setDisabled(true);
            else
                ui->selectFileButton->setDisabled(false);
        }
        else
        {
            ui->selectFileButton->setDisabled(true);

            if (m_bModify)
            {
                ui->typeComboBox->setDisabled(true);
                ui->nameEdit->setDisabled(false);
            }
            else
            {
                ui->nameEdit->setDisabled(false);
                ui->typeComboBox->setDisabled(false);
            }
        }
    }

    void ParaDefineDlg::OnTypeComboBoxTextChanged()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui != nullptr, L"ui为空", L"paramodel", L"2024-02-20");

        std::wstring typeName = ui->typeComboBox->currentText().toStdWString();
        if (typeName == L"材质")
        {
            // 计算出材质下拉列表中可见的内容
            if (ui->materialComboBox->count() < 1)
            {
                std::vector<std::wstring> itemNames = CalcItemNamesInMaterialComboBox();
                QStringList qItemNames;
                FOR_EACH(itemName, itemNames)
                {
                    qItemNames.push_back(QString::fromStdWString(itemName));
                }
                ui->materialComboBox->addItems(qItemNames);
            }

            ui->materialComboBox->setVisible(true);
            ui->materialComboBox->setCurrentIndex(0);
            ui->fomulalineedit->clear();
            ui->fomulalineedit->setVisible(false);
            ui->textStyeComboBox->setVisible(false);
            std::wstring text = L"材质";
            ui->label_3->setText(QString::fromStdWString(text));
        }
        else if (typeName == L"文字样式")
        {
            if (ui->textStyeComboBox->count() < 1)
            {
                std::vector<std::wstring> textStyleItemNames = CalcItemNamesOfRichTextComboBox();
                QStringList qTextStyleItemNames;
                FOR_EACH(textStyleItemName, textStyleItemNames)
                {
                    qTextStyleItemNames.push_back(QString::fromStdWString(textStyleItemName));
                }
                ui->textStyeComboBox->addItems(qTextStyleItemNames);
            }

            ui->textStyeComboBox->setVisible(true);
            ui->textStyeComboBox->setCurrentIndex(0);
            ui->fomulalineedit->clear();
            ui->fomulalineedit->setVisible(false);
            ui->materialComboBox->setVisible(false);
            std::wstring text = L"文字样式";
            ui->label_3->setText(QString::fromStdWString(text));
        }
        else
        {
            ui->materialComboBox->setVisible(false);
            ui->textStyeComboBox->setVisible(false);
            ui->fomulalineedit->setVisible(true);
            std::wstring text = L"值/表达式";
            ui->label_3->setText(QString::fromStdWString(text));
        }
    }

    void ParaDefineDlg::OnMaterialComboBoxTextChanged()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyManager, L"m_pFamilyManager为空指针", L"paramodel", L"2024-02-20");
        IDocument * pDoc = m_pFamilyManager->GetDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空指针", L"paramodel", L"2024-02-20");
        
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui, L"ui为空指针", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui->materialComboBox, L"ui->materialComboBox为空指针", L"paramodel", L"2024-02-20");
        std::wstring text = ui->materialComboBox->currentText().toStdWString();
        if (text == L"更多材质")
        {
        }
        else if(text == L"按类别")
        {
            m_materialId = ElementId::InvalidID;
        }
        else
        {
        }
    }

    void ParaDefineDlg::OnTextStyleComboBoxTextChanged()
    {
    }

    void gfam::ParaDefineDlg::OnHelpButtonClicked()
    {
        if (!m_exprAssistantDlg)
        {
            m_exprAssistantDlg = NEW_AS_OWNER_PTR(ExprAssistantDlg, this);
        }
        m_exprAssistantDlg->show();
    }

    void gfam::ParaDefineDlg::OnCursorPositionChanged()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui, L"ui为空指针", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui->fomulalineedit, L"ui->fomulalineedit为空指针", L"paramodel", L"2024-02-20");

        QCompleter *pCompleter = ui->fomulalineedit->completer();
        if (pCompleter)
        {
            DelimitedCompleter *pDelimitedCompleter = dynamic_cast<DelimitedCompleter *>(pCompleter);
            if (pDelimitedCompleter)
            {
                if (pDelimitedCompleter->GetPosition() != -1)
                {
                    ui->fomulalineedit->setCursorPosition(pDelimitedCompleter->GetPosition());
                }
            }
        }
    }

    void gfam::ParaDefineDlg::OnFormulaTextChangedInReplay()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui, L"ui为空指针", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui->fomulalineedit, L"fomulalineedit为空？", L"paramodel", L"2024-02-20");
        
        QCompleter * pCompleter = ui->fomulalineedit->completer();
        if (pCompleter)
        {
            pCompleter->complete();
        }
    }

    void ParaDefineDlg::UpdateMaterialComboBox(const std::wstring & materialName)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui, L"ui为空指针", L"paramodel", L"2024-02-20");

        // 计算出材质下拉列表中可见的内容
        std::vector<std::wstring> itemNames = CalcItemNamesInMaterialComboBox();

        // 计算下拉列表的当前项
        QStringList itemNames_4_qt;
        int currentComboBoxIndex = 0, iIndex = 0;
        FOR_EACH(itemName, itemNames)
        {
            itemNames_4_qt.push_back(QString::fromStdWString(itemName));
            if (itemName == materialName)
            {
                currentComboBoxIndex = iIndex;
            }

            iIndex++;
        }

        DBG_WARN_AND_RETURN_VOID_UNLESS(ui->materialComboBox, L"ui->materialComboBox为空指针", L"paramodel", L"2024-02-20");
        ui->materialComboBox->clear();
        ui->materialComboBox->addItems(itemNames_4_qt);
        ui->materialComboBox->setCurrentIndex(currentComboBoxIndex);
    }

    std::vector<std::wstring> ParaDefineDlg::CalcItemNamesOfRichTextComboBox()
    {
        std::vector<std::wstring> itemNames;
        return itemNames;
    }

    std::vector<std::wstring> gfam::ParaDefineDlg::CalcItemNamesInMaterialComboBox()
    {
        std::vector<std::wstring> itemNames;
        IDocument *pDoc = UiDocumentViewUtils::GetCurrentDocument();
        DBG_WARN_AND_RETURN_UNLESS(pDoc, itemNames, L"pDoc为空", L"paramodel", L"2024-02-20");
        IFamilyManager *pFamilyManager = IFamilyManager::Get(pDoc);
        DBG_WARN_AND_RETURN_UNLESS(pFamilyManager, itemNames, L"pFamilyManager为空", L"paramodel", L"2024-02-20");
        itemNames.push_back(L"按类别");

        // 文档中所有材质实例(material guid)
        std::vector<IGraphicsMaterial*> graphicsMaterials = IGraphicsMaterial::GetAllGraphicsMaterials(pFamilyManager->GetDocument());
        for (const IGraphicsMaterial* pGraphicsMaterial : graphicsMaterials)
        {
            // 针对类别的材质和材质实例不是一一绑定的，所以忽略
            if (pGraphicsMaterial->GetTargetCategoryUid().IsValid())
                continue;

            std::wstring materialName;
            bool isOk = pGraphicsMaterial->GetMaterialInstanceName(materialName);
            DBG_WARN_AND_CONTINUE_UNLESS(isOk, L"pGraphicsMaterial->GetMaterialInstanceName(materialName) 返回 false", L"paramodel", L"2024-02-20");
            itemNames.push_back(materialName);
        }

        itemNames.push_back(L"更多材质");

        return itemNames;
    }

    void gfam::ParaDefineDlg::InitCompleter()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(ui, L"ui为空指针", L"paramodel", L"2024-02-20");

        QStringList wordList;
        wordList << "函数：sin()" << "函数：cos()" << "函数：tan()" << "函数：asin()" << "函数：acos()" << "函数：atan()" << "函数：sqrt()" << "函数：pow()" << "函数：if()" << "函数：Round()" << "函数：Rounddown()" << "函数：Roundup()"<<"函数：size_lookup()";

        IDocument *pDoc = UiDocumentViewUtils::GetCurrentDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空", L"paramodel", L"2024-02-20");

        IFamilyManager *pFamilyManager = IFamilyManager::Get(pDoc);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pFamilyManager, L"pFamilyManager为空", L"paramodel", L"2024-02-20");

        std::vector<ElementId> paramDefineIds = pFamilyManager->GetFamilyParameterDefinitionIds();
        FOR_EACH(paramDefineId, paramDefineIds)
        {
            const IFamilyParameterDefinition* parameter = pFamilyManager->GetFamilyParameterDefinition(paramDefineId);

            if (!parameter)
                continue;

            if (!parameter->IsVisible())
            {
                // 在族环境下不可见，则不显示
                continue;
            }

            if (parameter->GetUid() == PARAMETER_UID(ColumnLayingTypeBuiltInParameter))
            {
                continue;
            }

            //不显示的参数不需要显示在对话框里
            if (parameter->GetParameterTypeId() == PARAMETER_TYPE(None) && !(parameter->GetStandardType() == ParameterStandardType::StandardEssential || parameter->GetStandardType() == ParameterStandardType::StandardExtended))
                continue;

            wordList << QString::fromStdWString(L"参数：" + parameter->GetName());
        }

        DelimitedCompleter* completer = NEW_AS_QT_CHILD(DelimitedCompleter, ui->fomulalineedit, wordList);
        completer->setFilterMode(Qt::MatchContains);
        completer->setCaseSensitivity(Qt::CaseSensitivity::CaseInsensitive);
    }

    void ParaDefineDlg::onMoveRequested(const QPoint& cursorPos, const QPoint& offset)
    {
        Q_UNUSED(cursorPos);
        move(pos() + offset);
    }

    void ParaDefineDlg::SwapParameterDefinitionDisplayOrder(int modifyParamIndex) const
    {
    }

    bool ParaDefineDlg::CheckParameterValue(int nType, const std::wstring & strValue)
    {
        FamilyParameterType fpt = (FamilyParameterType)nType;
        bool isParameterValueValid = false;
        switch (fpt)
        {
        case gfam::FamilyParameterType::Length:
        case gfam::FamilyParameterType::Angle:
        case gfam::FamilyParameterType::Double:
        case gfam::FamilyParameterType::Integer:
        {
            // 使用小数点的情况
            std::wstring str = L"-?(\\d+\\.\\d+)e[+-]\\d+";
            std::wregex regExp(str);
            if (std::regex_match(strValue, regExp))
            {
                isParameterValueValid = true;
            }

            // 科学计数法
            regExp.assign(L"-?((\\d+|\\d+\\.\\d+)|(\\d+\\.\\d+)e[+-]\\d+)");
            if (std::regex_match(strValue, regExp))
            {
                isParameterValueValid = true;
            }
        }
        break;
        case gfam::FamilyParameterType::Bool:
            if (strValue == L"是" || strValue == L"否")
            {
                isParameterValueValid = true;
            }
            break;
        case gfam::FamilyParameterType::String:
            isParameterValueValid = true;
            break;
        case gfam::FamilyParameterType::Material:
            break;
        case gfam::FamilyParameterType::TextStyle:
            break;
        default:
            break;
        }

        return isParameterValueValid;
    }

    bool gfam::ParaDefineDlg::ModifyParameterValue(const IFamilyParameterDefinition * pParam, const std::wstring & familyTypeName, const std::wstring & strValue)
    {
        if (m_pFamilyManager == nullptr || pParam == nullptr)
        {
            return false;
        }

        std::vector<const gcmp::IFamilyType*> familyTypes = m_pFamilyManager->GetFamilyTypes();
        if (familyTypes.empty())
        {
            return false;
        }
        FamilyParameterType fpt = pParam->GetParameterType();
        gcmp::ParameterStorageType pst = pParam->GetStorageType();
        switch (pst)
        {
        case gcmp::ParameterStorageType::Int:
        {
            if (!strValue.empty())
            {
                int nVal = StringUtil::ToNumber<int>(strValue);
                m_pFamilyManager->SetParameterValueAsInteger(familyTypeName, pParam, nVal);
            }
        }
        break;
        case gcmp::ParameterStorageType::Double:
        {
            double dVal = StringUtil::ToNumber<double>(strValue);

            if (pParam->GetUnitTypeId() == UNIT(Angle))//角度值进行弧度转换
            {
                dVal = dVal * Constants::MATH_PI / 180;
            }
            m_pFamilyManager->SetParameterValueAsDouble(familyTypeName, pParam, dVal);
        }
        break;
        case gcmp::ParameterStorageType::String:
        {
            m_pFamilyManager->SetParameterValueAsString(familyTypeName, pParam, strValue);
        }
        break;
        case gcmp::ParameterStorageType::Bool:
        {
            bool bValue = false;
            if (strValue == L"是")
            {
                bValue = true;
            }
            m_pFamilyManager->SetParameterValueAsBool(familyTypeName, pParam, bValue);
        }
        break;
        case gcmp::ParameterStorageType::ElementId:
        {
            if (fpt == FamilyParameterType::Material)
            {
                m_pFamilyManager->SetParameterValueAsElementId(familyTypeName, pParam, m_materialId);
            }
        }
        break;
        case gcmp::ParameterStorageType::Custom:
        {
        }
        break;
        default:
        {
            DBG_WARN(L"未处理的参数类型", L"paramodel", L"2024-02-20");
            return false;
        }
        }

        return true;
    }

    QString gfam::ParaDefineDlg::ParamValueToString(const IFamilyParameterDefinition * pParam)
    {
        DBG_WARN_AND_RETURN_UNLESS(m_pFamilyManager != nullptr, QString(), L"pFamilyManager为空", L"paramodel", L"2024-02-20");

        if (!pParam)
            return "";

        std::wstring typeName = m_pFamilyManager->GetCurrentFamilyTypeName();
        gcmp::ParameterStorageType storageType = pParam->GetStorageType();
        switch (storageType)
        {
        case gcmp::ParameterStorageType::Int:
        {
            int nVal = m_pFamilyManager->GetParameterValueAsInteger(typeName, pParam);
            return QString::number(nVal);
        }
        break;
        case gcmp::ParameterStorageType::Double:
        {
            double dVal = m_pFamilyManager->GetParameterValueAsDouble(typeName, pParam);
            if (pParam->GetUnitTypeId() == UNIT(Angle))//角度值进行弧度转换
            {
                dVal = dVal * 180 / Constants::MATH_PI;
            }

            if (IBehaviorConfig::GetConfigRecordValueAsString(BehaviorConfigRecordNames::ProductType) == ProductTypeRecordValues::FamilyEditor)
            {
                return QString::number(dVal, 'f', 2);
            }
            return QString::number(dVal, 'g', 12);
        }
        break;
        case gcmp::ParameterStorageType::String:
        {
            return QString::fromStdWString(m_pFamilyManager->GetParameterValueAsString(typeName, pParam));
        }
        break;
        case ParameterStorageType::Bool:
        {
            std::wstring sValue = L"否";
            if (m_pFamilyManager->GetParameterValueAsBool(typeName, pParam))
            {
                sValue = L"是";
            }
            return QString::fromStdWString(sValue);
        }
        break;
        default:
        break;
        }

        return "";
    }

    bool gfam::ParaDefineDlg::IsParamValueChanged(const IFamilyParameterDefinition * pParam, const std::wstring & strValue)
    {
        if (m_pFamilyManager == nullptr || pParam == nullptr)
        {
            return false;
        }

        std::vector<const gcmp::IFamilyType*> familyTypes = m_pFamilyManager->GetFamilyTypes();
        if (familyTypes.empty())
        {
            return false;
        }
        FamilyParameterType fpt = pParam->GetParameterType();
        gcmp::ParameterStorageType pst = pParam->GetStorageType();
        switch (pst)
        {
        case gcmp::ParameterStorageType::Int:
        {
            int nVal = StringUtil::ToNumber<int>(strValue);
            int value = m_pFamilyManager->GetParameterValueAsInteger(pParam);
            if (nVal != value)
            {
                return true;
            }
        }
        break;
        case gcmp::ParameterStorageType::Double:
        {
            double dVal = StringUtil::ToNumber<double>(strValue);

            if (pParam->GetUnitTypeId() == UNIT(Angle))//角度值进行弧度转换
            {
                dVal = dVal * Constants::MATH_PI / 180;
            }
            double value = m_pFamilyManager->GetParameterValueAsDouble(pParam);
            if (fabs(dVal - value) > Constants::DOUBLE_EPS)
            {
                return true;
            }
        }
        break;
        case gcmp::ParameterStorageType::String:
        {
            if (m_pFamilyManager->GetParameterValueAsString(pParam) != strValue)
            {
                return true;
            }
        }
        break;
        case gcmp::ParameterStorageType::Bool:
        {
            bool bValue = false;
            if (strValue == L"是")
            {
                bValue = true;
            }
            if (bValue != m_pFamilyManager->GetParameterValueAsBool(pParam))
            {
                return true;
            }
        }
        break;
        case gcmp::ParameterStorageType::ElementId:
        {
            if (fpt == FamilyParameterType::Material)
            {
                if (m_pFamilyManager->GetParameterValueAsElementId(pParam) != m_materialId)
                {
                    return true;
                }
            }
        }
        break;
        case gcmp::ParameterStorageType::Custom:
        {
        }
        break;
        default:
        {
            DBG_WARN(L"未处理的参数类型", L"paramodel", L"2024-02-20");
            return false;
        }
        }

        return false;
    }

    bool gfam::ParaDefineDlg::UpdateParamExprValues()
    {
        DBG_WARN_AND_RETURN_FALSE_UNLESS(m_pFamilyManager != nullptr, L"m_pFamilyManager为空", L"paramodel", L"2024-02-20");

        OwnerPtr<IExprEngine> opEngine = ExprHelper::CreateAndInitExprEngine(m_pFamilyManager);

        //获取族参数信息
        bool bFormulaValid = true;
        std::wstring message;

        std::vector<ElementId> paramDefineIds = m_pFamilyManager->GetFamilyParameterDefinitionIds();

        for (std::vector<ElementId>::iterator it = paramDefineIds.begin(); it != paramDefineIds.end(); it++)
        {
            const IFamilyParameterDefinition* parameter = m_pFamilyManager->GetFamilyParameterDefinition(*it);

            if (!parameter)
                continue;

            if (parameter->GetUid() == PARAMETER_UID(ColumnLayingTypeBuiltInParameter))
            {
                continue;
            }

            if (parameter->IsDeterminedByFormula())
            {
                double resultValue = 0;
                std::wstring strValue = L"";
                if (ExprHelper::UpdateParamExprValue(opEngine.get(), parameter, resultValue, strValue))
                {
                    ParameterStorageType paramStorageType = parameter->GetStorageType();
                    switch (paramStorageType)
                    {
                    case ParameterStorageType::Double:
                        m_pFamilyManager->SetParameterValueAsDouble(parameter, resultValue);
                        break;
                    case ParameterStorageType::Int:
                        m_pFamilyManager->SetParameterValueAsInteger(parameter, (int)(resultValue + 0.5));
                        break;
                    case ParameterStorageType::Bool:
                        m_pFamilyManager->SetParameterValueAsBool(parameter, (resultValue > 0.5) ? true : false);
                        break;
                    case ParameterStorageType::String:
                        m_pFamilyManager->SetParameterValueAsString(parameter, strValue);
                        break;
                    default:
                        DBG_WARN(L"暂未处理", L"paramodel", L"2024-02-20");
                    }
                }
                else
                {
                    message += parameter->GetName() + L"  : 表达式更新失败！ \n";
                    bFormulaValid = false;
                }
            }
        }

        if (!bFormulaValid)
        {
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), message, (int)UiCommonDialog::ButtonType::OK);
        }

        return bFormulaValid;
    }

    void ParaDefineDlg::UpdateParameterBindingInfo(int oldParamDefId, int newParamDefId)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyManager != nullptr, L"m_pFamilyManager为空", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyManager->GetDocument() != nullptr, L"m_pFamilyManager->GetDocument()为空", L"paramodel", L"2024-02-20");
        
        std::vector<IElement*> vecAllElement = m_pFamilyManager->GetDocument()->GetAllElements();
        FOR_EACH(pElement, vecAllElement)
        {
            DBG_WARN_AND_CONTINUE_UNLESS(pElement->GetElementParameters() != nullptr, L"pElement->GetElementParameters()为空", L"paramodel", L"2024-02-20");
            IElementParameterBindings* pBehavior = pElement->GetElementParameters()->GetElementParameterBindings();
            if (pBehavior)
            {
                auto& infos = pBehavior->GetParameterBindings();
                FOR_EACH(info, infos)
                {
                    if (info->GetSourceParameterDefinitionId() == oldParamDefId)
                    {
                        DBG_WARN_AND_CONTINUE_UNLESS(pElement->GetElementParameters()->GetElementParameterBindings() != nullptr, L"pElement->GetElementParameters()->GetElementParameterBindings()为空", L"paramodel", L"2024-02-20");
                        pElement->GetElementParameters()->GetElementParameterBindings()->ChangeParameterBinding(info->GetTargetParameterDefinitionId(), newParamDefId, m_pFamilyManager->GetElementId());
                    }
                }
            }
        }
    }

    void ParaDefineDlg::GetDimConstraintBoundToCurrentParam(std::vector<IFamilyDimensionConstraint *> &vecDimConstraintsBoundToCurParam)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyManager, L"m_pFamilyManager为空指针", L"paramodel", L"2024-02-20");
        IDocument* pDoc = m_pFamilyManager->GetDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空指针", L"paramodel", L"2024-02-20");
        std::vector<IElement*> vecFamDimConstraints = pDoc->GetElementsByCategoryIncludingInGroupType(BuiltInCategoryUniIdentities::BICU_FAM_CONSTRAINT);
        FOR_EACH(pItem, vecFamDimConstraints)
        {
            IFamilyDimensionConstraint *pDimConstraint = FamilyElementUtils::CastElement<IFamilyDimensionConstraint>(pItem);
            if (!pDimConstraint)
                continue;

            DBG_WARN_AND_CONTINUE_UNLESS(m_pModifedParaDefinition != nullptr, L"m_pModifedParaDefinition为空", L"paramodel", L"2024-02-20");
            if (pDimConstraint->GetFamilyParameterDefinitionId() == m_pModifedParaDefinition->GetElementId())
            {
                vecDimConstraintsBoundToCurParam.push_back(pDimConstraint);
            }
        }
    }


    void ParaDefineDlg::UpdateDimConstraintBoundToOldParam(std::vector<IFamilyDimensionConstraint *> vecDimConstraintsLinkedToCurParam, IFamilyParameterDefinition* pParam)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(pParam, L"pParam为空指针", L"paramodel", L"2024-02-20");

        FOR_EACH(pConstraint, vecDimConstraintsLinkedToCurParam)
        {
            DBG_WARN_AND_CONTINUE_UNLESS(pConstraint != nullptr, L"pConstraint为空", L"paramodel", L"2024-02-20");
            pConstraint->SetFamilyParameterDefinitionId(pParam->GetElementId());
        }
    }

    bool ParaDefineDlg::ModifyParameter(const std::wstring& strName, int nType, bool bInstance, bool bFomula, const std::wstring& strFomula, const std::wstring & strValue)
    {
        DBG_WARN_AND_RETURN_FALSE_UNLESS((int)m_pModifedParaDefinition->GetParameterType() == nType, L"参数类型不许修改", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_FALSE_UNLESS(m_pModifedParaDefinition != nullptr, L"m_pModifedPara为空", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_FALSE_UNLESS(m_pFamilyManager != nullptr, L"m_pFamilyManager为空", L"paramodel", L"2024-02-20");

        if (m_pModifedParaDefinition->GetParameterType() != (FamilyParameterType)nType)
        {
            // 参数类型不许修改
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), GBMP_TR(L"参数类型暂不允许修改"), (int)UiCommonDialog::ButtonType::OK);
            return false;
        }

        std::wstring strOldName = m_pModifedParaDefinition->GetName();
        bool oldIsInstance = m_pModifedParaDefinition->IsInstance();
        std::wstring oldFormula = m_pModifedParaDefinition->GetFormula();

        //判断是否存在同名参数
        if (strName != strOldName && m_pFamilyManager->GetFamilyParameterDefinition(strName) != nullptr)
        {
            //已有同名参数
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), GBMP_TR(L"系统已存在同名参数,请重新指定参数名称"), (int)UiCommonDialog::ButtonType::OK);
            return false;
        }

        // 记录修改前参数的位置
        int index = 0;
        int modifyParamIndex = 0;
        bool isNeedChangeDisplayOrder = false;
        std::vector<ElementId> paramDefineIds = m_pFamilyManager->GetFamilyParameterDefinitionIds();
        FOR_EACH(paramDefineId, paramDefineIds)
        {
            const IFamilyParameterDefinition* parameter = m_pFamilyManager->GetFamilyParameterDefinition(paramDefineId);
            if (parameter)
            {
                const gcmp::IElementBasicInformation * pBasicInformation = parameter->GetBasicInformation();
                DBG_WARN_AND_CONTINUE_UNLESS(pBasicInformation, L"pBasicInformation为空", L"paramodel", L"2024-02-20");
                if (pBasicInformation->GetName() == strOldName)
                {
                    modifyParamIndex = index;
                    break;
                }
            }

            ++index;
        }

        // 1 更新公式
        if (strFomula != oldFormula)
        {
            m_pFamilyManager->UpdateFamilyParameterDefinition(m_pModifedParaDefinition, strFomula);
        }

        // 2 更新类型
        if (bInstance != oldIsInstance)
        {
            m_pFamilyManager->UpdateFamilyParameterDefinition(m_pModifedParaDefinition, bInstance);
        }

        // 判断公式是否合法
        std::wstring strWarning;
        IDocument* pDoc = m_pFamilyManager->GetDocument();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空!", L"paramodel", L"2024-02-20");
        int ret = FormulaUtil::CheckParameterFormula(pDoc, m_pModifedParaDefinition, strWarning);
        if (ret != 0)
        {
            m_pFamilyManager->UpdateFamilyParameterDefinition(m_pModifedParaDefinition, oldFormula);
            m_pFamilyManager->UpdateFamilyParameterDefinition(m_pModifedParaDefinition, oldIsInstance);

            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), strWarning, (int)UiCommonDialog::ButtonType::OK);

            return false;
        }

        std::vector<const gcmp::IFamilyType*> familyTypes = m_pFamilyManager->GetFamilyTypes();
        if (strFomula.empty() && IsParamValueChanged(m_pModifedParaDefinition, strValue))
        {
            if (familyTypes.size() > 1)
            {
                if (UiCommonDialog::ButtonType::OK == UiCommonDialog::ShowMessageBox(GBMP_TR(L"提示"), L"参数值发生变化，是否同步到其他构件类别？", (int)UiCommonDialog::ButtonType::OK | (int)UiCommonDialog::ButtonType::Cancel))
                {
                    FOR_EACH(familyType, familyTypes)
                    {
                        ModifyParameterValue(m_pModifedParaDefinition, familyType->GetName(), strValue);
                    }
                }
                else
                {
                    ModifyParameterValue(m_pModifedParaDefinition, m_pFamilyManager->GetCurrentFamilyTypeName(), strValue);
                }
            }
            else
            {
                ModifyParameterValue(m_pModifedParaDefinition, m_pFamilyManager->GetCurrentFamilyTypeName(), strValue);
            }
        }

        DBG_WARN_AND_RETURN_FALSE_UNLESS(ui != nullptr, L"ui为空", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_FALSE_UNLESS(ui->radioSharedParameterButton != nullptr, L"ui->radioSharedParameterButton为空", L"paramodel", L"2024-02-20");
        if (ui->radioSharedParameterButton->isChecked() && m_pModifedParaDefinition->IsShared())
        {
            return true;
        }

        if (!(ui->radioSharedParameterButton->isChecked() || m_pModifedParaDefinition->IsShared()) && strName != strOldName)
        {
            {
                std::map<std::wstring, OwnerPtr<IParameter>> mapOldParamValue;
                int oldParamDefId, newParamDefId;
                bool isDriveParam = false;
                bool isGeometricParam = false;

                for (auto pFamilyType : m_pFamilyManager->GetFamilyTypes())
                {
                    auto typeName = pFamilyType->GetName();
                    const IParameter* pParam = m_pFamilyManager->GetParameter(typeName, m_pModifedParaDefinition);
                    DBG_WARN_AND_RETURN_FALSE_UNLESS(pParam != nullptr, L"pParam为空!", L"paramodel", L"2024-02-20");

                    mapOldParamValue[typeName] = pParam->Clone();
                }

                oldParamDefId = m_pFamilyManager->GetFamilyParameterDefinitionId(m_pModifedParaDefinition);

                //获取与旧参数相关的约束
                std::vector<IFamilyDimensionConstraint *> vecDimConstraintsBoundToCurParam;
                GetDimConstraintBoundToCurrentParam(vecDimConstraintsBoundToCurParam);

                isNeedChangeDisplayOrder = true;
                // 3 更新名称
                IFamilyParameterDefinition* pNewFamParamDefinition = IFamilyParameterDefinition::Create(m_pFamilyManager->GetDocument(), m_pModifedParaDefinition);
                pNewFamParamDefinition->SetName(strName);
                //pParam->SetParameterType(nType);

                m_pFamilyManager->RemoveFamilyParameterDefinition(m_pModifedParaDefinition);
                m_pModifedParaDefinition = nullptr;

                m_pFamilyManager->AddFamilyParameterDefinition(pNewFamParamDefinition);
                ExprHelper::RenameAllRefParams(m_pFamilyManager, strOldName, strName);

                //SetParaData(pParam, strName, (FamilyParameterType)nType, bInstance, bFomula);

                for (auto pFamilyType : m_pFamilyManager->GetFamilyTypes())
                {
                    auto typeName = pFamilyType->GetName();
                    auto& oldParam = mapOldParamValue[typeName];

                    const IParameter* pParameter = m_pFamilyManager->GetParameter(typeName, pNewFamParamDefinition);
                    DBG_WARN_AND_RETURN_FALSE_UNLESS(pParameter != nullptr, L"pParameter为空!", L"paramodel", L"2024-02-20");

                    OwnerPtr<IParameter> parameter = TransferOwnershipCast<IParameter>(pParameter->Clone());
                    DBG_WARN_AND_RETURN_FALSE_UNLESS(parameter != nullptr, L"parameter为空!", L"paramodel", L"2024-02-20");

                    DBG_WARN_AND_RETURN_FALSE_UNLESS(oldParam->GetParameterValueStorage() != nullptr, L"oldParam->GetParameterValueStorage()为空!", L"paramodel", L"2024-02-20");
                    parameter->SetParameterValueStorage(oldParam->GetParameterValueStorage()->Clone());
                    parameter->SetDriveParameter(oldParam->IsDriveParameter());
                    //parameter->SetGeometricParameter(oldParam->IsGeometricParameter());

                    m_pFamilyManager->SetParameter(typeName, TransferOwnership(parameter));
                }

                newParamDefId = m_pFamilyManager->GetFamilyParameterDefinitionId(pNewFamParamDefinition);

                //更新参数绑定信息
                UpdateParameterBindingInfo(oldParamDefId, newParamDefId);
                //更新尺寸约束
                UpdateDimConstraintBoundToOldParam(vecDimConstraintsBoundToCurParam, pNewFamParamDefinition);
            }
        }
        if (isNeedChangeDisplayOrder)
        {
            SwapParameterDefinitionDisplayOrder(modifyParamIndex);
        }
        return true;
    }

    bool ParaDefineDlg::CreateNewParameter(const std::wstring& strName, int nType, bool bInstance, bool bFomula, const std::wstring& strFomula, const std::wstring & strValue)
    {
        DBG_WARN_AND_RETURN_FALSE_UNLESS(m_pFamilyManager != nullptr, L"m_pFamilyManager为空", L"paramodel", L"2024-02-20");
        DBG_WARN_AND_RETURN_FALSE_UNLESS(ui != nullptr, L"ui为空", L"paramodel", L"2024-02-20");

        // 临时代码开始：材料库分类标识
        FamilyParameterType fpt = (FamilyParameterType)nType;

        if (strName == L"分类标识-26A94DE5-002C-4780-9C05-3AD815FE5AEA")
        {
            if (fpt != FamilyParameterType::String)
            {
                UiCommonDialog::ShowMessageBox(L"错误", L"分类识别参数类型只能是文字。", (int)UiCommonDialog::ButtonType::OK);
                return false;
            }

            if (bInstance)
            {
                UiCommonDialog::ShowMessageBox(L"错误", L"分类识别参数不能是实例。", (int)UiCommonDialog::ButtonType::OK);
                return false;
            }

        }
        // 临时代码结束：材料库分类标识
        if (m_pFamilyManager->GetFamilyParameterDefinition(strName) != nullptr)
        {
            UiCommonDialog::ShowMessageBox(L"错误", L"系统已经存在同名参数，请重新指定参数名称。", (int)UiCommonDialog::ButtonType::OK);
            return false;
        }

        bool userVisible = true, userModifiable = true;

        //创建族参数定义
        IFamilyParameterDefinition* pParam = IFamilyParameterDefinition::Create(m_pFamilyManager->GetDocument(), strName, fpt, bInstance, L"");
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pParam, L"pParam为空", L"paramodel", L"2024-02-20");

        if (strName == L"分类标识-26A94DE5-002C-4780-9C05-3AD815FE5AEA")
        {
            pParam->SetParameterType(FamilyParameterType::Internal);
        }

        if (ui->radioSharedParameterButton->isChecked() && m_sharedParaData)
        {
            //如果是共享参数

            OwnerPtr<IParameterValueList> opValueList = m_sharedParaData->ValueList ? m_sharedParaData->ValueList->Clone() : nullptr;

            if (opValueList)
            {
                pParam->SetParameterTypeId(PARAMETER_TYPE(ValueList));
                pParam->SetValueList(TransferOwnership(opValueList)); //设置值列表
            }

            pParam->SetGroupName(m_sharedParaData->GroupName);
            pParam->SetDescription(m_sharedParaData->Desc);
            pParam->SetShared(true);
            pParam->SetUid(m_sharedParaData->Uid); //设置配置的Uid

            userVisible = m_sharedParaData->UserVisible;
            userModifiable = m_sharedParaData->UserModifiable;
        }

        //添加定义到族管理器中去
        m_pFamilyManager->AddFamilyParameterDefinition(pParam, userVisible, userModifiable);
        DBG_WARN_AND_RETURN_FALSE_UNLESS(quick_cast<IFamilyManager>(m_pFamilyManager) != nullptr, L"FamilyManager为空", L"paramodel", L"2024-02-20");

        std::vector<const gcmp::IFamilyType*> familyTypes = m_pFamilyManager->GetFamilyTypes();
        FOR_EACH(familyType, familyTypes)
        {
            ModifyParameterValue(pParam, familyType->GetName(), strValue);
        }

        if (bFomula && pParam != nullptr)
        {
            pParam->SetFormula(strFomula);
            //参数值的更新依赖表达式的计算，这里设置处理类型为输出，则在属性面板中显示为灰色，不可编辑状态。
            m_pFamilyManager->SetFamilyParameterProcessType(pParam, ParameterProcessType::GeneralOutput);
        }

        // 先检查新创建的表达式，再检查所有的表达式
        std::wstring strWarning;
        IDocument* pDoc = m_pFamilyManager->GetDocument();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pDoc, L"pDoc为空!", L"paramodel", L"2024-02-20");
        int ret = FormulaUtil::CheckParameterFormula(pDoc, pParam, strWarning);
        if (ret != 0)
        {
            UiCommonDialog::ShowMessageBox(GBMP_TR(L"错误"), strWarning, (int)UiCommonDialog::ButtonType::OK);
            m_pFamilyManager->RemoveFamilyParameterDefinition(pParam);

            return false;
        }
        else
        {
            std::wstring parameterType = ConvertParameterType(fpt);
        }

        return true;
    }

}

